/**
 * 版权所有 2009-2012山东新北洋信息技术股份有限公司
 * 保留所有权利。
 */
package com.linyaonan.leetcode.easy._443;

/**
 * 给定一组字符，使用原地算法将其压缩。
 * <p>
 * 压缩后的长度必须始终小于或等于原数组长度。
 * <p>
 * 数组的每个元素应该是长度为1 的字符（不是 int 整数类型）。
 * <p>
 * 在完成原地修改输入数组后，返回数组的新长度。
 * <p>
 *  
 * <p>
 * 进阶：
 * 你能否仅使用O(1) 空间解决问题？
 * <p>
 *  
 * <p>
 * 示例 1：
 * <p>
 * 输入：
 * ["a","a","b","b","c","c","c"]
 * <p>
 * 输出：
 * 返回6，输入数组的前6个字符应该是：["a","2","b","2","c","3"]
 * <p>
 * 说明：
 * "aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
 * 示例 2：
 * <p>
 * 输入：
 * ["a"]
 * <p>
 * 输出：
 * 返回1，输入数组的前1个字符应该是：["a"]
 * <p>
 * 说明：
 * 没有任何字符串被替代。
 * 示例 3：
 * <p>
 * 输入：
 * ["a","b","b","b","b","b","b","b","b","b","b","b","b"]
 * <p>
 * 输出：
 * 返回4，输入数组的前4个字符应该是：["a","b","1","2"]。
 * <p>
 * 说明：
 * 由于字符"a"不重复，所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
 * 注意每个数字在数组中都有它自己的位置。
 * 注意：
 * <p>
 * 所有字符都有一个ASCII值在[35, 126]区间内。
 * 1 <= len(chars) <= 1000。
 *
 * @ProjectName: leetcode
 * @Package: com.linyaonan.leetcode.easy._443
 * @ClassName: StringCompression
 * @Author: linyaonan
 * @Date: 2019/12/30 13:42
 */
public class StringCompression {

    public int compress(char[] chars) {
        if (chars.length == 1) {
            return 1;
        }
        char start = chars[0];
        int tCount = 1;
        int cIndex = 1;
        for (int i = 1; i < chars.length; i++) {
            if (chars[i] == start) {
                tCount++;
            } else {
                cIndex = dealWithNum(chars, tCount, cIndex, chars[i]);
                start = chars[i];
                tCount = 1;
            }
        }
        if (tCount != 0) {
            cIndex = dealWithNum(chars, tCount, cIndex, null);
        }
        return cIndex;
    }

    /**
     * 处理多位数字情况
     *
     * @param chars  原始数组
     * @param tCount 计数器
     * @param cIndex 不同字符的修改下标
     * @param p      尾部添加的字符
     * @return cIndex
     */
    private int dealWithNum(char[] chars, int tCount, int cIndex, Character p) {
        if (tCount > 1) {
            String numStr = String.valueOf(tCount);
            int l = numStr.toCharArray().length;
            for (int i = 0; i < l; i++) {
                chars[cIndex + i] = numStr.charAt(i);
            }
            cIndex += l;
        }
        if (p != null) {
            chars[cIndex] = p;
            cIndex++;
        }
        return cIndex;
    }
}
